'''
Created on Jul 16, 2010

@author: riche
'''

from ft.framework import application, component
from ft.framework.net_io import *
from ft.directory import localhost
from ft.apps.messages import agree_msgs

class AgreeAbstractionComp(component.Implementation):
    
    def __init__(self, name, node_name):
        component.Implementation.__init__(self, name)
        self._node_name = node_name
        self.__curr_seq_no__ = 0
    
    def handle_request(self, msg):
        print('Queueing this: ' + msg)
        if self._node_name == localhost.AGREE0_NAME:
            message = agree_msgs.CommMsg(self.__curr_seq_no__, msg)
            self.send_out('out', (localhost.BCAST_AGREES_NAME, message.get_body()))
            exec_message = agree_msgs.ExecMsg(self.__curr_seq_no__, msg)
            #self.send_out('out', (localhost.QA_NAME, exec_message.get_body()))
            self.send_out('out', (localhost.BCAST_SERVERS_NAME, exec_message.get_body()))
            self.__curr_seq_no__ += 1
        else:
            message = agree_msgs.Message(msg)
            if message.cmd == agree_msgs.FTCMD_COM:
                new_message = agree_msgs.ExecMsg(message.seq_no, message.internals)
                #self.send_out('out', (localhost.QA_NAME,new_message.get_body()))
                self.send_out('out', (localhost.BCAST_SERVERS_NAME,new_message.get_body()))

class Agreement(application.Application):
    '''
    SCFT Agreement node application
    '''

    def __init__(self):
        '''
        Constructor
        '''
        application.Application.__init__(self)
        
    def setup(self):
        
        agree_comp = AgreeAbstractionComp('agree_comp', self._node_name)
        self.create_component(agree_comp, [('in', 'handle_request'), ('out', '__OUT__')])
        
        nr = net_reader.NetReaderComponent(self._node_name, localhost.local_directory)
        nw = net_writer.NetWriterComponent('netout', self._node_name, localhost.local_directory)
        
        self.add_components([nr, nw])
        
        nr_to_agree = self.create_connection((self._node_name, 'out'), ('agree_comp', 'in'))
        agree_to_nw = self.create_connection(('agree_comp', 'out'),('netout','in'))

        nr_thread = application.CompThread(nr, [nr_to_agree], True)
        nw_thread = application.CompThread(nw, [agree_to_nw])
        agree_thread = application.CompThread(agree_comp, [nr_to_agree, agree_to_nw])

        self.add_threads([nr_thread, nw_thread, agree_thread])
        
if __name__ == '__main__':
    agree = Agreement()
    agree.parse_opts()
    agree.setup()
    agree.execute()
